package p42_lockStudy.code;

import java.util.concurrent.atomic.AtomicReference;

/**
 * CLH锁
 * CLH 锁是一种隐式的链表队列，没有显式的维护前驱或后继指针。
 * 因为每个等待获取锁的线程只需要轮询前一个节点的状态就够了，而不需要遍历整个队列。
 * 在这种情况下，只需要使用一个局部变量保存前驱节点，而不需要显式的维护前驱或后继指针。
 *
 * 通过代码可以看到，还是存在自旋问题，当锁持有时间长时，还是会带来CPU的开销。
 * 还有则是基本的CLH锁功能单一，不改造不能支持复杂的场景。
 */
public class CLH {

    private static class Node{
        private volatile boolean locked;
    }

    //初始node为false
    private final ThreadLocal<Node> node = ThreadLocal.withInitial(Node::new);
    //初始tail为false
    private final AtomicReference<Node> tail = new AtomicReference<>(new Node());

    public void lock() {
        Node node = this.node.get();
        node.locked = true;
        Node pre = this.tail.getAndSet(node);
        //如果上一个节点为false,则成功获取了锁，
        // 将执行完毕，否则将一直等待释放
        while (pre.locked);
    }

    public void unlock() {
        final Node node = this.node.get();
        // 释放锁
        node.locked = false;
        this.node.set(new Node());
    }

}
